<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>穿梭框</title>
    <script src="https://unpkg.com/vue@2.7.14/dist/vue.min.js"></script>
    <style>
        *{
            margin:0;
            padding: 0;
            list-style: none;
        }
        ul{
            border:1px solid #666;
            width: 100px;
            height: 200px;
            padding: 10px;
            margin: 10px;
        }

        li:hover{
            background-color: #eee;;
            cursor: pointer;
        }
        button{
            min-width: 20px;
        }
    </style>
</head>
<body style="padding: 20px">
<div id="app">
    <h1>穿梭框</h1>
    <div style="display: flex">

        <ul>
            <div>
            <input type="checkbox" v-model="LeftCheck" id="allLeftCheck"><label for="allLeftCheck">全选</label>
            </div>
            <hr>
          <li v-for="h in heroes">
               <input  type="checkbox" v-model="h.selected"><label>{{h.name}}</label>
           </li>
        </ul>
        <div style="padding-top: 50px">
            <button @click="moveLeft"> < </button>
            <br>
            <button @click="moveRight"> > </button>
        </div>
        <ul>
            <div>
                <input type="checkbox"  id="allRightCheck" v-model="RightCheck"><label for="allRightCheck">全选</label>
            </div>
            <hr>
            <li v-for="h1 in heroes1">
                <input type="checkbox" v-model="h1.selected" ><label>{{h1.name}}</label>
            </li>
        </ul>
    </div>
</div>
<script>
    /*
        1.两个下拉菜单select+左右移动按钮
        2.全选：计算属性get+set
        3.左右移动：数组元素移动
     */
    var Hero = function(name, alias, p, i, a,selected) {
        this.name = name;
        this.alias = alias;
        this.p = p;
        this.i = i;
        this.a = a;
        this.selected=selected;
    }
    var v = new Vue({
        el: "#app",
        data: {
            heroes: [
                new Hero("林冲", "豹子头", 99, 85, 90,false),
                new Hero("武松", "行者", 98, 80, 88,false),
                new Hero("秦明", "霹雳火", 95, 82, 85,false),
                new Hero("白胜", "白日鼠", 75, 80, 85,false),
                new Hero("石秀", "拼命三郎", 97, 82, 83,false),
            ],
            heroes1:[],
            leftCurPage: false,
            rightCurPage:false,
        },
        methods:{
            /**
             * 把左边的选出来 移动到右边
             * 筛选出来左边的元素
             * 选中的元素添加到右边
             */
            moveRight(){


                /**
                 * 复制选上的元素到arr
                 * @type {BigInt64Array}
                 * @warring这种方法有两个问题,一是移动后的数据是默认选上的，需要取消，二是移动后原数据还在
                 */
                const arr=this.heroes.filter(heroes=>heroes.selected)
                this.heroes1.push(...arr);

                /**
                 * 删除选中元素，等价于留下未选中的元素
                 * @type {BigInt64Array}
                 * @warring filter不会改变原数组，也就不会出发v-for更新，需要覆盖
                 */
                this.heroes=this.heroes.filter(heroes=>!heroes.selected)


                /*
                 * 取消移动后的右边选区的选择状态
                 * 一定要先删除后取消选中，否则会使原数组已经处于未选中状态导致无法删除
                 */
                arr.forEach(heroes1=>heroes1.selected=false)



            },
            moveLeft(){
                const arr=this.heroes1.filter(heroes1=>heroes1.selected)
                this.heroes.push(...arr);
                this.heroes1=this.heroes1.filter(heroes1=>!heroes1.selected)
                arr.forEach(heroes=>heroes.selected=false)

            },
        },
        computed: {
            /**
             * 全选事件
             */
            LeftCheck: {
                //如果数组为空，无条件返回false
                get() {
                    if(this.heroes.length===0){
                        return  false;
                    }
                    //判断左边数字是否全部被选中
                    return this.heroes.every(heroes => heroes.selected)
                },
                set(val) {
                    //修改数组中每一个元素select为val
                    return this.heroes.forEach(heroes => heroes.selected = val)
                }
            },
            RightCheck: {

                get() {
                    if(this.heroes1.length===0){
                        return  false;
                    }
                    //判断左边数字是否全部被选中
                    return this.heroes1.every(heroes1 => heroes1.selected)
                },
                set(val) {
                    //修改数组中每一个元素select为val
                    return this.heroes1.forEach(heroes1 => heroes1.selected = val)
                }
            },
        }
    })
</script>
</body>
</html>